package com.windsea.relationshipmining.api;

import java.util.ArrayList;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Event;

import com.windsea.relationshipmining.database.DBUserData;
import com.windsea.relationshipmining.model.Address;
import com.windsea.relationshipmining.model.Contact;
import com.windsea.relationshipmining.model.ContactList;
import com.windsea.relationshipmining.model.Email;
import com.windsea.relationshipmining.model.IM;
import com.windsea.relationshipmining.model.Organization;
import com.windsea.relationshipmining.model.Phone;

public class ContactApi {

	private Cursor cur = null;
	private ContentResolver cr = null;

	public Cursor getCur() {
		return cur;
	}

	public void setCur(Cursor cur) {
		this.cur = cur;
	}

	public ContentResolver getCr() {
		return cr;
	}

	public void setCr(ContentResolver cr) {
		this.cr = cr;
	}

	// Construtor with content resolver
	public ContactApi(ContentResolver cr) {
		this.cr = cr;
	}

	// Get Contact List
	public ContactList getContactList() {
		ContactList contacts = new ContactList();
		String id;
		this.cur = this.cr.query(ContactsContract.Contacts.CONTENT_URI, null,
				null, null, null);
		if (this.cur.getCount() > 0) {
			while (cur.moveToNext()) {
				Contact c = new Contact();
				id = cur.getString(cur
						.getColumnIndex(ContactsContract.Contacts._ID));
				c.setContactid(id);
				c.setName(cur.getString(cur
						.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));

				c.setEmail(this.getEmailAddresses(id));
				c.setNote(this.getContactNotes(id));
				c.setAddress(this.getContactAddresses(id));
				c.setIm(this.getIM(id));
				c.setOrganization(this.getContactOrg(id));
				c.setHasProfilePhoto(this.hasProfilePicture(id));
				if (this.hasAnniversaryDay(id) == 1
						|| this.hasBirthday(id) == 1) {
					c.setHasAnnivesaryDay(1);
				} else {
					c.setHasAnnivesaryDay(0);
				}
				if (Integer
						.parseInt(cur.getString(cur
								.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
					c.setPhone(this.getPhoneNumbers(id));
					contacts.addContact(c);
				}

			}
		}
		this.cur.close();
		return (contacts);
	}

	public ArrayList<Phone> getPhoneNumbers(String id) {
		ArrayList<Phone> phones = new ArrayList<Phone>();

		Cursor pCur = this.cr.query(
				ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
				ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
				new String[] { id }, null);
		while (pCur.moveToNext()) {
			phones.add(new Phone(
					pCur.getString(pCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)),
					phoneType(pCur.getInt(pCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)))));

		}
		pCur.close();
		return (phones);
	}

	public ArrayList<Email> getEmailAddresses(String id) {
		ArrayList<Email> emails = new ArrayList<Email>();

		Cursor emailCur = this.cr.query(
				ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
				ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
				new String[] { id }, null);
		while (emailCur.moveToNext()) {
			// This would allow you get several email addresses
			Email e = new Email(
					emailCur.getString(emailCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)),
					emailCur.getString(emailCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)));
			emails.add(e);
		}
		emailCur.close();
		return (emails);
	}

	public ArrayList<String> getContactNotes(String id) {
		ArrayList<String> notes = new ArrayList<String>();
		String where = ContactsContract.Data.CONTACT_ID + " = ? AND "
				+ ContactsContract.Data.MIMETYPE + " = ?";
		String[] whereParameters = new String[] { id,
				ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE };
		Cursor noteCur = this.cr.query(ContactsContract.Data.CONTENT_URI, null,
				where, whereParameters, null);
		while (noteCur.moveToNext()) {
			String note = noteCur
					.getString(noteCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Note.NOTE));
			if (note.length() > 0) {
				notes.add(note);
			}
		}
		noteCur.close();
		return (notes);
	}

	public ArrayList<Address> getContactAddresses(String id) {
		ArrayList<Address> addrList = new ArrayList<Address>();

		String where = ContactsContract.Data.CONTACT_ID + " = ? AND "
				+ ContactsContract.Data.MIMETYPE + " = ?";
		String[] whereParameters = new String[] {
				id,
				ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE };

		Cursor addrCur = this.cr.query(ContactsContract.Data.CONTENT_URI, null,
				where, whereParameters, null);
		while (addrCur.moveToNext()) {
			String poBox = addrCur
					.getString(addrCur
							.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX));
			String street = addrCur
					.getString(addrCur
							.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
			String city = addrCur
					.getString(addrCur
							.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
			String state = addrCur
					.getString(addrCur
							.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
			String postalCode = addrCur
					.getString(addrCur
							.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
			String country = addrCur
					.getString(addrCur
							.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));
			String type = addrCur
					.getString(addrCur
							.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE));
			Address a = new Address(poBox, street, city, state, postalCode,
					country, type);
			addrList.add(a);
		}
		addrCur.close();
		return (addrList);
	}

	public ArrayList<IM> getIM(String id) {
		ArrayList<IM> imList = new ArrayList<IM>();
		String where = ContactsContract.Data.CONTACT_ID + " = ? AND "
				+ ContactsContract.Data.MIMETYPE + " = ?";
		String[] whereParameters = new String[] { id,
				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE };

		Cursor imCur = this.cr.query(ContactsContract.Data.CONTENT_URI, null,
				where, whereParameters, null);
		while (imCur.moveToNext()) {
			String imName = imCur.getString(imCur
					.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA));
			String imType;
			imType = imCur
					.getString(imCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Im.PROTOCOL));
			if (imName.length() > 0) {
				IM im = new IM(imName, imType);
				imList.add(im);
			}
		}
		imCur.close();
		return (imList);
	}

	public ArrayList<Organization> getContactOrg(String id) {
		ArrayList<Organization> orgs = new ArrayList<Organization>();
		String where = ContactsContract.Data.CONTACT_ID + " = ? AND "
				+ ContactsContract.Data.MIMETYPE + " = ?";
		String[] whereParameters = new String[] { id,
				ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE };

		Cursor orgCur = this.cr.query(ContactsContract.Data.CONTENT_URI, null,
				where, whereParameters, null);

		while (orgCur.moveToNext()) {
			String orgName = orgCur
					.getString(orgCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Organization.DATA));
			String title = orgCur
					.getString(orgCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE));
			String type = orgCur
					.getString(orgCur
							.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TYPE));
			if (orgName.length() > 0) {
				Organization org = new Organization(orgName, title, type);
				orgs.add(org);
			}
		}
		orgCur.close();
		return (orgs);
	}

	public int hasProfilePicture(String id) {
		Cursor picCur = null;
		try {

			picCur = this.cr
					.query(ContactsContract.Data.CONTENT_URI,
							null,
							ContactsContract.Data.CONTACT_ID
									+ "="
									+ id
									+ " AND "
									+ ContactsContract.Data.MIMETYPE
									+ "='"
									+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
									+ "'", null, null);
			if (picCur != null) {
				if (!picCur.moveToFirst()) {
					picCur.close();
					return 0; // no photo
				}
			} else {
				return 0; // error in cursor process
			}
		} catch (Exception e) {
			e.printStackTrace();
			picCur.close();
			return 0;
		}
		picCur.close();
		return 1;
	}

	public int hasBirthday(String id) {
		Cursor birCur = null;
		try {
			String columns[] = {
					ContactsContract.CommonDataKinds.Event.START_DATE,
					ContactsContract.CommonDataKinds.Event.TYPE,
					ContactsContract.CommonDataKinds.Event.MIMETYPE, };

			String where = Event.TYPE + "=" + Event.TYPE_BIRTHDAY + " and "
					+ Event.MIMETYPE + " = '" + Event.CONTENT_ITEM_TYPE
					+ "' and " + ContactsContract.Data.CONTACT_ID + " = " + id;

			birCur = this.cr.query(ContactsContract.Data.CONTENT_URI, columns,
					where, null, null);
			if (birCur != null) {
				if (!birCur.moveToFirst()) {
					birCur.close();
					return 0;
				}
			} else {
				return 0;
			}
		} catch (Exception e) {
			e.printStackTrace();
			birCur.close();
			return 1;
		}
		birCur.close();

		return 1;
	}

	public int hasAnniversaryDay(String id) {
		Cursor birCur = null;
		try {
			String columns[] = {
					ContactsContract.CommonDataKinds.Event.START_DATE,
					ContactsContract.CommonDataKinds.Event.TYPE,
					ContactsContract.CommonDataKinds.Event.MIMETYPE, };

			String where = Event.TYPE + "=" + Event.TYPE_ANNIVERSARY + " and "
					+ Event.MIMETYPE + " = '" + Event.CONTENT_ITEM_TYPE
					+ "' and " + ContactsContract.Data.CONTACT_ID + " = " + id;

			birCur = this.cr.query(ContactsContract.Data.CONTENT_URI, columns,
					where, null, null);
			if (birCur != null) {
				if (!birCur.moveToFirst()) {
					birCur.close();
					return 0;
				}
			} else {
				return 0;
			}
		} catch (Exception e) {
			e.printStackTrace();
			birCur.close();
			return 1;
		}
		birCur.close();

		return 1;
	}

	public static String contactIdFinder(String phonenumber, Context context) {
		String contactId = null;

		DBUserData dbUserData = new DBUserData(context);
		dbUserData.open();
		contactId = dbUserData.getContactIdByPhonenumber(phonenumber);
		dbUserData.close();
		dbUserData = null;
		return contactId;
	}

	public static String phoneNumberProcess(String phonenumber) {
		if (phonenumber == null) {
			phonenumber = "unknown";
		}
		phonenumber.trim();
		// xử lý dấu +

		// xử lý dấu cách
		if (phonenumber.indexOf(" ") > 0) {
			phonenumber = phonenumber.replace(" ", "");
			// xử lý số đầu dấu gạch ngang
		}
		if (phonenumber.indexOf("-") > 0) {

			phonenumber = phonenumber.replace("-", "");
			// xử lý số đầu +84
		}
		if (phonenumber.indexOf("84", 1) > 0) {
			phonenumber = phonenumber.replace("+84", "0");
		}
		phonenumber = phonenumber.replace("+", "");

		return phonenumber;
	}

	/* Specify interpretation of Phone-Type */
	public String phoneType(int t) {

		String g = null;

		switch (t) {
		case Phone.TYPE_MOBILE:
			g = "Mobile";
			break;
		case Phone.TYPE_HOME:
			g = "Home";
			break;
		case Phone.TYPE_WORK:
			g = "Work";
			break;
		default:
			g = "Other";
			break;
		}
		return g;

	}
}
